package com.example.MyRESTAssured.restAsurred;

import com.github.fge.jsonschema.cfg.ValidationConfiguration;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import io.restassured.RestAssured;
import io.restassured.module.jsv.JsonSchemaValidator;
import io.restassured.parsing.Parser;
import io.restassured.response.Response;
import org.junit.Test;
import java.math.BigDecimal;
import static com.github.fge.jsonschema.SchemaVersion.DRAFTV3;
import static com.github.fge.jsonschema.SchemaVersion.DRAFTV4;
import static io.restassured.RestAssured.*;
import static io.restassured.config.JsonConfig.jsonConfig;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
import static io.restassured.module.jsv.JsonSchemaValidatorSettings.settings;
import static io.restassured.path.json.config.JsonPathConfig.NumberReturnType.*;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsCollectionContaining.hasItems;
import static org.junit.Assert.assertThat;


public class RestAssuredTest {

    /**
     * 验证GET请求，设置请求的返回类型
     * 验证数据相等，验证数据包含
     * 请求一次就可以了，不要反复请求
     */
    @Test
    public void TestmakeGetRequest(){
        RestAssured.registerParser("text/plain",Parser.JSON);
        Response response=get("/lotto");
        response.then().body("lotto.lottoId", equalTo(5));
        System.out.println("验证属性值相等成功！");

        response.then().body("lotto.winners.winnerId", hasItems(23, 54));
        System.out.println("验证属性值有个多取值成功！");

        System.out.println("GET 请求测试成功!");
    }

    /**
     * 验证数据的类型，包括float，double,BigDecimal
     * is()和equalTo()方法只能验证小数中的float类型，而必须添加f后缀
     * 验证double类型，需要事件配置获取的返回着的类型
     *
     * bug:不能使用Big_decimal进行数字验证，如果按照文档进行编写，显示期望值是<33.32999999>,实际值33.33
     * 如果is方法里面是33.33,则报错显示期望值是<33.33>,实际值33.33
     *
     * new BigDecimal是，如果参数是数字类型，计算机内部表示的是近似值值，所以有精度问题，需要人为保留小数点的位数
     * 如果是字符串类型，就可以正常的生成指定小数点的数字类型
     *
     * @return
     */
    @Test
    public void TestvalidateNumberTypeGetRequest() {

        double a = 11.11d;
        if (11.11 == a) {
            System.out.println("ok");
        }

        RestAssured.registerParser("text/plain", Parser.JSON);
        Response response = get("/number");

        response.then().body("price", equalTo(11.11f));
        System.out.println("验证equalTo能够比较float类型相等成功！");

        response.then().body("price", is(11.11f));
        System.out.println("验证float值相等成功！");

        given().config(RestAssured.config().jsonConfig(jsonConfig().numberReturnType(DOUBLE))).
                when().
                get("/number").
                then().
                body("money", is(22.22));
        System.out.println("验证double值相等成功！");

        given().config(RestAssured.config().jsonConfig(jsonConfig().numberReturnType(BIG_DECIMAL))).
                when().
                get("/number").
                then().
                body("cash", is(new BigDecimal(33.33).setScale(2,BigDecimal.ROUND_CEILING)));

        given().config(RestAssured.config().jsonConfig(jsonConfig().numberReturnType(BIG_DECIMAL))).
                when().
                get("/number").
                then().
                body("cash", is(new BigDecimal("33.33")));
        System.out.println("验证BigDecimal的创建验证成功！");

        System.out.println("验证BigDecimal值相等成功！");
    }

    /**
     * 使用json schema文件验证请求的json是否满足指定的说明格式
     * using()最终多会创建一个JsonSchemaValidator
     * @return
     */
    @Test
    public void TestvalidateJsonSchemaGetRequest(){

        //1.最简化的验证json schema
        Response response = get("/schema");
        response.then().assertThat().body(matchesJsonSchemaInClasspath("products-schema.json"));
        System.out.println("json schema验证返回json的正确性成功！");

        //2.配置底层的json-schema-validator库,传递参数JsonSchemaFactory
        JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.newBuilder().setValidationConfiguration(ValidationConfiguration.newBuilder().setDefaultVersion(DRAFTV4).freeze()).freeze();
        get("/schema").then().assertThat().body(matchesJsonSchemaInClasspath("products-schema.json").using(jsonSchemaFactory));
        System.out.println("json schema验证返回json的正确性成功！使用默认的JsonSchemaFactory底层配置");

        //3.默认的JsonSchemaFactory可以设置validation是否检查,默认是检查的。也可以自定义JsonSchemaValidatorSettings
        get("/schema").then().assertThat().body(matchesJsonSchemaInClasspath("products-schema.json").using(settings().with().checkedValidation(false)));
        System.out.println("json schema验证返回json的正确性成功！使用JsonSchemaValidatorSettings设置validation是否可以检查");

        //4.设置全部的默认json模式版本为3。DRAFTV3是版本3的意思
        JsonSchemaValidator.settings = settings().with().jsonSchemaFactory( JsonSchemaFactory.newBuilder().setValidationConfiguration(  ValidationConfiguration.newBuilder()
                                                                                                                                                               .setDefaultVersion(DRAFTV3)
                                                                                                                                                               .freeze()
                                                                                                                                     )
                                                                                             .freeze()
                                                                          )
                                                        .and()
                                                        .with()
                                                        .checkedValidation(false);
        get("/schema").then().assertThat().body(matchesJsonSchemaInClasspath("products-schema.json"));
        System.out.println("超复杂的单独设置配置器验证细节！");

        //5.将设置的各种配置重置
        JsonSchemaValidator.reset();
        System.out.println("json shemad的配置重置！");

        //6.直接使用字符串验证是否匹配json schema文件.
        String json="{\n" +
                "\t\"id\": 10,\n" +
                "\t\"name\": \"jxiong\",\n" +
                "\t\"price\": 20\n" +
                "}";
        assertThat(json, matchesJsonSchemaInClasspath("products-schema.json"));

        System.out.println("测试json schema验证json格式成功!");
    }

    /**
     * 测试匿名json根的数据，没有大括号和key值
     * 使用$符号表示根元素
     * @return
     */
    @Test
    public void TestvalidateAnonymousJSONRootGetRequest() {

        RestAssured.registerParser("text/plain", Parser.JSON);
        when().get("/anonymous")
                .then()
                .body("$", hasItems(1, 2, 3));

        System.out.println("测试匿名json根的验证成功！");
    }

}
